<!doctype html>
<html class="no-js" lang="">

<head>
    <meta charset="utf-8">
    <meta content="ie=edge,chrome=1" http-equiv="x-ua-compatible">
    <title>动态多数据源监控</title>
    <meta content="" name="description">
    <meta content="width=device-width, initial-scale=1, shrink-to-fit=no" name="viewport">

    <link href="css/normalize.css" rel="stylesheet">
    <link href="css/main.css" rel="stylesheet">
    <link href="js/vendor/layui/css/layui.css" rel="stylesheet">
</head>

<body class="layui-layout-body">
<div class="layui-layout layui-layout-admin">
    <div class="layui-header">
        <div class="layui-logo">动态多数据源监控</div>
        <!-- 头部区域（可配合layui已有的水平导航） -->
        <ul class="layui-nav layui-layout-right" lay-filter="headerNav">
            <li class="layui-nav-item layui-this"><a href="javascript:void(0);" id="sqlStatus">SQL监控</a></li>
            <li class="layui-nav-item"><a href="javascript:void(0);" id="sqlExecuteStatus">SQL执行顺序监控</a></li>
            <li class="layui-nav-item"><a href="javascript:void(0);" id="datasourceStatus">数据源监控</a></li>
        </ul>
    </div>

    <div class="layui-side layui-bg-black sql">
        <div class="layui-side-scroll">
            <!-- 左侧导航区域（可配合layui已有的垂直导航） -->
            <ul class="layui-nav layui-nav-tree" id="dsList">
            </ul>
        </div>
    </div>

    <div class="layui-body sql">
        <!-- 内容主体区域 -->
        <div style="padding: 15px;">
            <table class="layui-hide" id="sqlTable" lay-filter="statusTable"></table>
        </div>
    </div>
    <div class="ds" style="padding: 15px;">
        <table class="layui-hide" id="dataSourceTable" lay-filter="statusTable"></table>
    </div>
    <div class="layui-footer sql" style=" text-align:center">
        <!-- 底部固定区域 -->
        © layui.com - 底部固定区域
    </div>
</div>
<script src="js/vendor/modernizr-3.6.0.min.js"></script>
<script src="js/vendor/jquery-3.3.1.min.js"></script>
<script src="js/plugins.js"></script>
<script src="js/main.js"></script>
<script src="js/vendor/layui/layui.js"></script>
</body>
<script>
    let layer, element, table, laytpl, currentSqlDS;
    layui.use(['layer', 'element', 'table', 'laytpl'], function () {
        layer = layui.layer;
        element = layui.element;
        table = layui.table;
        laytpl = layui.laytpl;
        init();
    });

    //初始化
    function init() {
        changePage("sql");
        element.on('nav(headerNav)', function (elem) {
            console.log(elem); //得到当前点击的DOM对象
            switch (elem[0].id) {
                case 'sqlStatus':
                    changePage("sql");
                    break;
                case 'datasourceStatus':
                    changePage("ds");
                    break;
            }
        });

        initDSMonitor();
        initSqlMonitor();
        /**
         * 刷新数据
         */
        table.on('toolbar(statusTable)', function (obj) {
            switch (obj.event) {
                case 'refreshDataSource':
                    table.reload('dataSourceTable');
                    break;
                case 'refreshSQL':
                    table.reload('sqlTable');
                    break;
            }
        });

        window.setInterval(function () {
            table.reload('dataSourceTable');
            table.reload('sqlTable');
            updateSqlDS();
        }, 30000);
    }

    function initDSMonitor() {
        /**
         * 初始化数据原监控
         */
        table.render({
            elem: '#dataSourceTable'
            , url: 'dsstats'
            , height: 'full-130'
            , page: false
            , toolbar: "#toolbarDatasource"
            , cellMinWidth: 150 //全局定义常规单元格的最小宽度，layui 2.2.1 新增
            , cols: [[
                {field: 'poolName', title: '数据池名称', rowspan: 2}
                , {field: 'url', title: '数据库地址', rowspan: 2} //width 支持：数字、百分比和不填写。你还可以通过 minWidth 参数局部定义当前单元格的最小宽度，layui 2.2.1 新增
                , {
                    field: 'connectivityCheck', title: '连通状态', align: 'center', rowspan: 2, templet: function (d) {
                        if (d.connectivityCheck == 'true') {
                            return '<span class="layui-badge layui-bg-green">正常</span>';
                        } else if (d.connectivityCheck == 'false') {
                            return '<span class="layui-badge">失败</span>';
                        } else {
                            return '<span class="layui-badge layui-bg-gray">未知</span>';
                        }
                    }
                }
                , {field: 'totalConnections', title: '连接总数', rowspan: 2}
                , {field: 'idleConnections', title: '空闲连接总数', rowspan: 2}
                , {field: 'activeConnections', title: '活动连接总数', rowspan: 2}
                , {field: 'pendingConnections', title: '请求连接总数', rowspan: 2} //单元格内容水平居中
                , {title: '获取连接的等待时间', colspan: 15} //单元格内容水平居中
                , {title: '连接使用时长', colspan: 11}
            ], [
                {
                    field: 'wait.count', title: '总次数', templet: function (d) {
                        return d.wait.count;
                    }
                }
                , {
                    field: 'wait.meanRate', title: '平均速率', templet: function (d) {
                        return "每秒 " + d.wait.meanRate + " 次";
                    }
                }
                , {
                    field: 'wait.m1Rate', title: '1分钟平均速率', templet: function (d) {
                        return "每秒 " + d.wait.m1Rate + " 次";
                    }
                }
                , {
                    field: 'wait.m5Rate', title: '5分钟平均速率', templet: function (d) {
                        return "每秒 " + d.wait.m5Rate + " 次";
                    }
                }
                , {
                    field: 'wait.m15Rate', title: '15分钟平均速率', templet: function (d) {
                        return "每秒 " + d.wait.m15Rate + " 次";
                    }
                }
                , {
                    field: 'wait.min', title: '最短等待时间', templet: function (d) {
                        return d.wait.min + " 毫秒";
                    }
                }
                , {
                    field: 'wait.max', title: '最长等待时间', templet: function (d) {
                        return d.wait.max + " 毫秒";
                    }
                }
                , {
                    field: 'wait.mean', title: '平均等待时间', templet: function (d) {
                        return d.wait.mean + " 毫秒";
                    }
                }
                , {
                    field: 'wait.stdDev', title: '标准偏差', templet: function (d) {
                        return d.wait.stdDev;
                    }
                }
                , {
                    field: 'wait.p50', title: '等待时间中间值', templet: function (d) {
                        return "= " + d.wait.p50 + " 毫秒";
                    }
                }
                , {
                    field: 'wait.p75', title: '75%等待时间', templet: function (d) {
                        return "<= " + d.wait.p75 + " 毫秒";
                    }
                }
                , {
                    field: 'wait.p95', title: '95%等待时间', templet: function (d) {
                        return "<= " + d.wait.p95 + " 毫秒";
                    }
                }
                , {
                    field: 'wait.p98', title: '98%等待时间', templet: function (d) {
                        return "<= " + d.wait.p98 + " 毫秒";
                    }
                }
                , {
                    field: 'wait.p99', title: '99%等待时间', templet: function (d) {
                        return "<= " + d.wait.p99 + " 毫秒";
                    }
                }
                , {
                    field: 'wait.p999', title: '99.9%等待时间', templet: function (d) {
                        return "<= " + d.wait.p999 + " 毫秒";
                    }
                }

                , {
                    field: 'usage.count', title: '总次数', templet: function (d) {
                        return d.usage.count;
                    }
                }
                , {
                    field: 'usage.min', title: '最短等待时间', templet: function (d) {
                        return d.usage.min + " 毫秒";
                    }
                }
                , {
                    field: 'usage.max', title: '最长等待时间', templet: function (d) {
                        return d.usage.max + " 毫秒";
                    }
                }
                , {
                    field: 'usage.mean', title: '平均等待时间', templet: function (d) {
                        return d.usage.mean + " 毫秒";
                    }
                }
                , {
                    field: 'usage.stdDev', title: '标准偏差', templet: function (d) {
                        return d.usage.stdDev;
                    }
                }
                , {
                    field: 'usage.p50', title: '等待时间中间值', templet: function (d) {
                        return "= " + d.usage.p50 + " 毫秒";
                    }
                }
                , {
                    field: 'usage.p75', title: '75%等待时间', templet: function (d) {
                        return "<= " + d.usage.p75 + " 毫秒";
                    }
                }
                , {
                    field: 'usage.p95', title: '95%等待时间', templet: function (d) {
                        return "<= " + d.usage.p95 + " 毫秒";
                    }
                }
                , {
                    field: 'usage.p98', title: '98%等待时间', templet: function (d) {
                        return "<= " + d.usage.p98 + " 毫秒";
                    }
                }
                , {
                    field: 'usage.p99', title: '99%等待时间', templet: function (d) {
                        return "<= " + d.usage.p99 + " 毫秒";
                    }
                }
                , {
                    field: 'usage.p999', title: '99.9%等待时间', templet: function (d) {
                        return "<= " + d.usage.p999 + " 毫秒";
                    }
                }
            ]]
            , parseData: function (res) { //将原始数据解析成 table 组件所规定的数据
                return {
                    "code": 0, //解析接口状态
                    "msg": '获取数据成功', //解析提示文本
                    "count": res.length, //解析数据长度
                    "data": res //解析数据列表
                };
            }


        });
    }

    function updateSqlDS() {
        $.ajax({
            url: 'queryds'
            , dataType: "json"
            , success: function (data, textStatus) {
                if (data == null || data == undefined || data == '')
                    return;
                var tplData = { //数据
                    "list": data
                };
                var getTpl = $("#sqlSide").html()
                    , view = $('#dsList');
                laytpl(getTpl).render(tplData, function (html) {
                    view.html(html);
                    element.render('nav');
                    reloadSqlStatus(currentSqlDS);
                });
            }
        });

    }

    function initSqlMonitor() {
        updateSqlDS();
        table.render({
            elem: '#sqlTable'
            , url: 'querystats'
            , height: 'full-180'
            , page: false
            , toolbar: "#toolbarSql"
            , cellMinWidth: 150 //全局定义常规单元格的最小宽度，layui 2.2.1 新增
            , cols: [[
                {field: 'id', title: 'ID'}
                , {field: 'url', title: 'url'}
                , {field: 'category', title: '种类'} //width 支持：数字、百分比和不填写。你还可以通过 minWidth 参数局部定义当前单元格的最小宽度，layui 2.2.1 新增
                , {field: 'sql', title: 'SQL'}

                , {
                    field: 'status.count', title: '执行次数', templet: function (d) {
                        return d.status.count;
                    }
                }
                , {
                    field: 'status.min', title: '最小执行时间', align: 'right', templet: function (d) {
                        return d.status.min + " 毫秒";
                    }
                }
                , {
                    field: 'status.max', title: '最大执行时间', align: 'right', templet: function (d) {
                        return d.status.max + " 毫秒";
                    }
                } //单元格内容水平居中
                , {
                    field: 'status.mean', title: '平均执行值', align: 'right', templet: function (d) {
                        return d.status.mean + " 毫秒";
                    }
                } //单元格内容水平居中
                , {
                    field: 'status.stdDev', title: '标准偏差', align: 'right', templet: function (d) {
                        return d.status.stdDev;
                    }
                }
                , {
                    field: 'status.p50', title: '执行时间中间值', align: 'right', templet: function (d) {
                        return "= " + d.status.p50 + " 毫秒";
                    }
                }
                , {
                    field: 'status.p75', title: '75%执行时间', align: 'right', templet: function (d) {
                        return "<= " + d.status.p75 + " 毫秒";
                    }
                }
                , {
                    field: 'status.p95', title: '95%执行时间', align: 'right', templet: function (d) {
                        return "<= " + d.status.p95 + " 毫秒";
                    }
                }
                , {
                    field: 'status.p98', title: '98%执行时间', align: 'right', templet: function (d) {
                        return "<= " + d.status.p98 + " 毫秒";
                    }
                }
                , {
                    field: 'status.p99', title: '99%执行时间', align: 'right', templet: function (d) {
                        return "<= " + d.status.p99 + " 毫秒";
                    }
                }
                , {
                    field: 'status.p999', title: '99.9%执行时间', align: 'right', templet: function (d) {
                        return "<= " + d.status.p999 + " 毫秒";
                    }
                }
            ]]
            , parseData: function (res) { //将原始数据解析成 table 组件所规定的数据
                return {
                    "code": 0, //解析接口状态
                    "msg": '获取数据成功', //解析提示文本
                    "count": res.length, //解析数据长度
                    "data": res //解析数据列表
                };
            }
        });

    }

    function changePage(page) {
        if (page == 'ds') {
            $(".sql").hide();
            $(".ds").show();
        } else {
            $(".sql").show();
            $(".ds").hide();
        }
    }

    function reloadSqlStatus(id) {
        table.reload('sqlTable', {
            where: {
                id: id
            }
        });
    }
</script>
<script id="sqlSide" type="text/html">
    {{#  layui.each(d.list, function(index, item){ }}
    {{#
    if(
    ((currentSqlDS==null||currentSqlDS==undefined||currentSqlDS=='') && index==0)||currentSqlDS==item.id
    ){
    currentSqlDS=item.id;
    }}
    <li class="layui-nav-item layui-this">
        {{#
        }else{
        }}
    <li class="layui-nav-item ">
        {{#
        }
        }}

        <a href="javascript:void(0);" onclick="reloadSqlStatus('{{item.id}}')" title="{{item.url}}">{{item.url}}</a>
    </li>
    {{#  }); }}
</script>
<script id="toolbarSql" type="text/html">
    <div class="layui-btn-container">
        <button class="layui-btn layui-btn-sm" lay-event="refreshSQL">刷新</button>
    </div>
</script>
<script id="toolbarDatasource" type="text/html">
    <div class="layui-btn-container">
        <button class="layui-btn layui-btn-sm" lay-event="refreshDataSource">刷新</button>
    </div>
</script>
</html>
